package com.eric.study.jobflow.job;

import com.eric.study.jobflow.graph.JobNodeDigraph;
import lombok.NonNull;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p> JobEngine.
 *
 * <p>
 * change history:
 *
 * <pre>
 * date         defect       person          comments
 * --------------------------------------------------------------------------------
 * 2023/8/31    ********     Eric    create file.
 * </pre>
 *
 * @author Eric
 * @date 2023/8/31 11:13
 * @copyright 2023, FA Software (Shanghai) Co., Ltd. All Rights Reserved.
 * @since 1.0.0
 */
public class JobEngine {

    private final JobNodeDigraph digraph;

    public JobEngine() {
        this.digraph = new JobNodeDigraph();
    }

    public JobNodeDigraph digraph() {
        return this.digraph;
    }

    public void addNode(@NonNull JobNode<?, ?> node) {
        this.digraph.addNode(node);
    }

    // node1 -> node2
    public void addEdge(@NonNull JobNode<?, ?> node1, JobNode<?, ?> node2) {
        this.digraph.addEdge(node1, node2);
    }

    public Set<JobNode<?, ?>> firstExecutableNodes() {
        return this.digraph.allNodes().stream().filter(node -> node.inDegree() == 0).collect(Collectors.toSet());
    }

    public Set<JobNode<?, ?>> nextExecutableNodes(@NonNull JobNode<?, ?> node) {
        return this.digraph.adjacencyVertices(node.getNumber())
                .stream()
                .map(no -> this.digraph.nodeMap().get(no))
                .collect(Collectors.toSet());
    }
}
